#include <iostream>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>
#include <string>

using namespace std;
#define NUM 10

__thread int g_val=0;

__thread pid_t pid=0;
__thread unsigned long int tid=0;


// C++中结构体类型创建实例不需要写struct，c++中类型与class类似
struct Thread_Data
{
	string name;
};

void Thread_Inin(Thread_Data* td,int number)
{
	td->name="thraed-"+to_string(number);
}

string toHex(pthread_t td)
{
	char buffer[1024];
	snprintf(buffer,sizeof(buffer),"0x%lx",td);
	return buffer;
}


void* Thread_Routine(void* arg)
{
	Thread_Data* td=static_cast<Thread_Data*>(arg);
	int i=0;
	tid=pthread_self();
	pid=getpid();
	while(i<10)
	{
		 cout<<"pid: " <<pid<<",tid: "<<toHex(tid)<<", threadname: "<<td->name<<' '
		 << "g_val: "<<g_val<<" &g_val: "<<&g_val<<endl;
		 sleep(1);
		 i++,g_val++;
	}
	delete td;
	return nullptr;
}


int main()
{
	vector<pthread_t> tds;
	// pthread_t tid;
	// Thread_Data td;
	// Thread_Inin(&td,1);
	// pthread_create(&tid,nullptr,Thread_Routine,&td);
	// pthread_join(tid,nullptr);
	for(int i=0;i<NUM;i++)
	{
		pthread_t tid;
		//Thread_Data td; 这里不能使用这种方式定义，首先就是这里出了for循环就被销毁了，但是如果我们没在for循环里面呢？
		// 因为我们创建线程的时候，虽然把值传了过去，但是由于只能传地址，所以我们传给线程的是地址，并且是栈上的地址，
		//而理论上其他线程是不能访问的，但实际上是可以访问的， 毕竟都在同一个虚拟地址空间，有什么不能访问的，但是这样就有会面临一个问题
		//	就是当线程结束了，该线程开始回收变量，因为其他线程的栈是开在共享区的，结果就发现了一个是真正栈上的地址，然后就报错了，
		Thread_Data* td =new Thread_Data;
		Thread_Inin(td,i);
		pthread_create(&tid,nullptr,Thread_Routine,td);
		tds.push_back(tid);
		sleep(1);
	}
	for(int i=0;i<NUM;i++)
	{
		pthread_join(tds[i],nullptr);
	}
	return 0;
}


